# include "VD_Crypto.h"

//#pragma code_seg()
NTSTATUS VD_CloseFile (
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP Irp)
{
	PDEVICE_EXTENSION		device_extension;
    PIO_STACK_LOCATION		io_stack;
	NTSTATUS				status;
	ULONG					ReadFileSystemTypeCrypted[2];
	UCHAR					FileSystemTypeDecrypted[9];
	UCHAR					FileSystemTypeDecrypted1[6];
	LARGE_INTEGER			ReadOffset; 
		SIZE_T				t; 
 	
	DbgPrint("CloseFile\n");
	  

	device_extension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
	ReadOffset.QuadPart = PassOffset;
	
	status = ZwReadFile(
						  device_extension->file_handle,
						  NULL,
						  NULL,
						  NULL,
						  &Irp->IoStatus,
						  (PVOID*)ReadFileSystemTypeCrypted,
						  LONGSIZE*2,
					      &ReadOffset,
						  NULL
							);
		
	if (!NT_SUCCESS(status)){
		DbgPrint("Unable to read filesystem type from file %x \n", status);
		Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
        return STATUS_UNSUCCESSFUL;    
	}

	if ((ReadFileSystemTypeCrypted[0] == 0) && (ReadFileSystemTypeCrypted[1] == 0))
	{
		DbgPrint("Raw FileSystem \n");
		device_extension->DeleteDevice = TRUE;
	}
	
	else{
		VD_BF_Decrypt(&device_extension->ctx,&ReadFileSystemTypeCrypted[0], &ReadFileSystemTypeCrypted[1]);
	
		//DbgPrint("System type %d %d \n",ReadFileSystemTypeCrypted[0],ReadFileSystemTypeCrypted[1]);

		RtlCopyMemory(
					FileSystemTypeDecrypted,
					ReadFileSystemTypeCrypted,
					LONGSIZE*2
					);		

		if (RtlCompareMemory((FileSystemTypeDecrypted + 3) , NTFS_Disk,sizeof(NTFS_Disk)-1) == sizeof(NTFS_Disk)-1){
			DbgPrint("NTFS \n");
			device_extension->DeleteDevice = FALSE;	
		}
		else if(RtlCompareMemory((FileSystemTypeDecrypted +3), FAT_Disk,sizeof(FAT_Disk)-1) == sizeof(FAT_Disk)-1){
			DbgPrint("FAT \n");
			device_extension->DeleteDevice = TRUE;
		}
		else{ 
			DbgPrint("Unknown FileSystem \n");
			device_extension->DeleteDevice = FALSE;
		}
	}

	device_extension->disk_mounted = FALSE;
	//Delete File Name
    ExFreePoolWithTag(device_extension->file_name.Buffer,POOL_TAG);
	
	ExFreePoolWithTag(device_extension->password,POOL_TAG);
	//Close Disk File Handle
	ZwClose(device_extension->file_handle);

	//Delete disk registry key
	ZwDeleteKey(device_extension->RegPathHandle);	

    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
	
	DbgPrint("Close File refcount %d \n",DeviceObject->ReferenceCount);
    return STATUS_SUCCESS;
}
